﻿// 2018/8/24: 首个记录
// 2018/11/29: 增加Protocols静态属性
// 2019/3/22: 时间戳赋值
// 2019/3/29: 添加注释
// 2020/1/14: 接口完备性
// 2021/4/6: 基于ASEvaAPI 2.0
// 2022/11/3: 使用SetTime复制全部时间信息
// 2023/10/10: 补充部分英文注释
// 2025/3/31: 实现ToGeneralSample方法
// 2025/4/7: 改为实现ToGeneralSample(channel)方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ASEva;

namespace FreespaceSampleV1
{
    class FreespaceSample : Sample
    {
        public List<FloatPoint[]> Sequences { get; set; } // [m] List of point sequences (Freespace can be described in multiple sequences) / 可行驶区域顶点列表(可多段描述)

        public FreespaceSample()
        {
            Sequences = new List<FloatPoint[]>();
        }

        public static string Title
        {
            get
            {
                return "Sequence count,First seq's offset, First seq's point count,etc";
            }
        }

        public static string Protocol
        {
            get
            {
                return "freespace-sample-v1";
            }
        }

        public static string[] Protocols
        {
            get
            {
                return new string[] { "freespace-sample-v1" };
            }
        }

        public override string GetGeneralSampleProtocol()
        {
            return Protocol;
        }

        public override string[] GetGeneralSampleProtocols()
        {
            return Protocols;
        }

        public override bool FromGeneralSample(GeneralSample sample)
        {
            SetTime(sample);

            if (sample.Protocol == "freespace-sample-v1")
            {
                var v = sample.Values.ToArray();
                if (v.Length < 1) return false;
                if (v[0].IsNotNumber()) return false;

                int seqCount = (int)v[0].number;
                if (v.Length < 1 + 2 * seqCount) return false;

                int seqBase = 1;
                int ptBase = seqBase + 2 * seqCount;

                var list = new List<FloatPoint[]>();
                for (int i = 0; i < seqCount; i++)
                {
                    int ptOffset = (int)v[seqBase + 2 * i].number;
                    int ptCount = (int)v[seqBase + 2 * i + 1].number;
                    if (v.Length < ptBase + 2 * (ptOffset + ptCount)) return false;

                    var pts = new FloatPoint[ptCount];
                    for (int n = 0; n < ptCount; n++)
                    {
                        pts[n].X = (float)v[ptBase + 2 * (ptOffset + n)].number;
                        pts[n].Y = (float)v[ptBase + 2 * (ptOffset + n) + 1].number;
                    }

                    list.Add(pts);
                }
                Sequences = list;

                return true;
            }

            return false;
        }

        public override GeneralSample ToGeneralSample(int channel)
        {
            GeneralSample result = new GeneralSample();
            result.SetTime(this);
            result.Protocol = Protocol;
            result.Channel = channel;
            
            if (Sequences == null || Sequences.Count == 0)
            {
                // 如果没有序列，只添加序列计数为0
                result.Values = new List<GeneralSampleValue> { new GeneralSampleValue(0.0) };
                result.NumberOfSignificants = 1;
                return result;
            }
            
            // 计算点的总数
            int pointCount = 0;
            for (int i = 0; i < Sequences.Count; i++)
            {
                pointCount += Sequences[i].Length;
            }
            
            // 创建数组，预先分配足够的空间
            // 格式：[序列数量, 序列1偏移量, 序列1点数, 序列2偏移量, 序列2点数, ..., 点1X, 点1Y, 点2X, 点2Y, ...]
            var values = new GeneralSampleValue[1 + 2 * (Sequences.Count + pointCount)];
            
            int seqBase = 1;
            int ptBase = seqBase + 2 * Sequences.Count;
            
            // 设置序列数量
            values[0] = new GeneralSampleValue((double)Sequences.Count);
            
            // 循环处理每个序列
            pointCount = 0;
            for (int i = 0; i < Sequences.Count; i++)
            {
                FloatPoint[] pts = Sequences[i];
                
                // 设置点偏移量和点数量
                values[seqBase + 2 * i] = new GeneralSampleValue((double)pointCount);
                values[seqBase + 2 * i + 1] = new GeneralSampleValue((double)pts.Length);
                
                // 设置点坐标
                for (int n = 0; n < pts.Length; n++)
                {
                    values[ptBase + 2 * (pointCount + n)] = new GeneralSampleValue((double)pts[n].X);
                    values[ptBase + 2 * (pointCount + n) + 1] = new GeneralSampleValue((double)pts[n].Y);
                }
                
                pointCount += pts.Length;
            }
            
            result.Values = values.ToList();
            result.NumberOfSignificants = values.Length;
            
            return result;
        }
    }
}
